home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / pas / swag / math.swg / 0053_Expression Evaluator.pas < prev    next >
Pascal/Delphi Source File  |  1994-01-27  |  5KB  |  252 lines

  1. {
  2. >Does anyone have any source for evaluating math expressions? I would like to
  3. >find some source that can evaluate an expression like
  4. >
  5. > 5 * (3 + 4)  or B * 3 + C
  6. }
  7.  
  8. Program Test;
  9.  
  10. Uses
  11.   Strings; {You have to use your own unit}
  12.  
  13. Var
  14.   x : Real;
  15.   maxvar : Integer;
  16.   s : String;
  17.  
  18. Const
  19.   maxfun = 21;
  20.   func : Array[1..maxfun] Of String[9] =
  21.            ('LN', 'SINH', 'SIN', 'COSH', 'COS', 'TANH', 'TAN', 'COTH', 'COT',
  22.             'SQRT', 'SQR', 'EXP', 'ARCSIN', 'ARSINH', 'ARCCOS', 'ARCOSH',
  23.             'ARCTAN', 'ARTANH', 'ARCCOT', 'ARCOTH', 'NEG');
  24.  
  25. Var
  26.   errnum : Integer;
  27.  
  28. Function Calculate(f : String) : Real;
  29.  
  30. Var
  31. {  errnum : Integer;}
  32.   eps : Real;
  33.  
  34.   Function Eval(l, r : Integer) : Real;
  35.  
  36.   Var
  37.     i, j, k, wo, op : Integer;
  38.     result, t1, t2 : real;
  39.  
  40.   Begin
  41.     If errnum > 0 Then Exit;
  42.     wo := 0; op := 6; k := 0;
  43.  
  44.     While (f[l] = '(') And (f[r] = ')') Do Begin
  45.       Inc(l); Dec(r);
  46.     End;
  47.  
  48.     If l > r Then Begin
  49.       errnum := 1; eval := 0.0; Exit;
  50.     End;
  51.  
  52.     For i := l To r Do Begin
  53.  
  54.        Case f[i] of
  55.           '(':  Inc(k);
  56.           ')':  Dec(k);
  57.           Else If k = 0 Then
  58.             Case f[i] of
  59.  
  60.               '+' : Begin
  61.                 wo := i; op := 1
  62.               End;
  63.  
  64.               '-' : Begin
  65.                 wo := i; op := 2
  66.               End;
  67.  
  68.               '*' : If op > 2 Then Begin
  69.                 wo := i; op := 3
  70.               End;
  71.  
  72.               '/' : If op > 2 Then Begin
  73.                 wo := i; op := 4
  74.               End;
  75.  
  76.               '^' : If op > 4 Then Begin
  77.                 wo := i; op := 5
  78.               End;
  79.  
  80.           End;
  81.        End;
  82.     End;
  83.  
  84.     If k <> 0 Then Begin
  85.       errnum := 2; eval := 0.0; Exit;
  86.     End;
  87.  
  88.     If op < 6 Then Begin
  89.        t1 := eval(l, wo-1); If errnum > 0 Then Exit;
  90.        t2 := eval(wo+1, r); If errnum > 0 Then Exit;
  91.     End;
  92.  
  93.     Case op of
  94.        1 : Begin
  95.          eval := t1 + t2;
  96.        End;
  97.  
  98.        2 : Begin
  99.          eval := t1 - t2;
  100.        End;
  101.  
  102.        3 : Begin
  103.          eval := t1 * t2;
  104.        End;
  105.  
  106.        4 : Begin
  107.          If Abs(t2) < eps Then Begin errnum := 4; eval := 0.0; Exit; End;
  108.          eval := t1 / t2;
  109.        End;
  110.  
  111.        5 : Begin
  112.          If t1 < eps Then Begin errnum := 3; eval := 0.0; Exit; End;
  113.          eval := exp(t2*ln(t1));
  114.        End;
  115.  
  116.        6 : Begin
  117.  
  118.          i:=0;
  119.          Repeat
  120.            Inc(i);
  121.          Until (i > maxfun) Or (Pos(func[i], f) = l);
  122.  
  123.          If i <= maxfun Then t1 := eval(l+length(func[i]), r);
  124.          If errnum > 0 Then Exit;
  125.  
  126.          Case i Of
  127.            1 : Begin
  128.              eval := ln(t1);
  129.            End;
  130.  
  131.            2 : Begin
  132.              eval := (exp(t1)-exp(-t1))/2;
  133.            End;
  134.  
  135.            3 : Begin
  136.              eval := sin(t1);
  137.            End;
  138.  
  139.            4 : Begin
  140.              eval := (exp(t1)+exp(-t1))/2;
  141.            End;
  142.  
  143.            5 : Begin
  144.              eval := cos(t1);
  145.            End;
  146.  
  147.            6 : Begin
  148.              eval := exp(-t1)/(exp(t1)+exp(-t1))*2+1;
  149.            End;
  150.  
  151.            7 : Begin
  152.              eval := sin(t1)/cos(t1);
  153.            End;
  154.  
  155.            8 : Begin
  156.              eval := exp(-t1)/(exp(t1)-exp(-t1))*2+1;
  157.            End;
  158.  
  159.            9 : Begin
  160.              eval := cos(t1)/sin(t1);
  161.            End;
  162.  
  163.           10 : Begin
  164.             eval := sqrt(t1);
  165.           End;
  166.  
  167.           11 : Begin
  168.             eval := sqr(t1);
  169.           End;
  170.  
  171.           12 : Begin
  172.             eval := exp(t1);
  173.           End;
  174.  
  175.           13 : Begin
  176.             eval := arctan(t1/sqrt(1-sqr(t1)));
  177.           End;
  178.  
  179.           14 : Begin
  180.             eval := ln(t1+sqrt(sqr(t1+1)));
  181.           End;
  182.  
  183.           15 : Begin
  184.             eval := -arctan(t1/sqrt(1-sqr(t1)))+pi/2;
  185.           End;
  186.  
  187.           16 : Begin
  188.             eval := ln(t1+sqrt(sqr(t1-1)));
  189.           End;
  190.  
  191.           17 : Begin
  192.             eval := arctan(t1);
  193.           End;
  194.  
  195.           18 : Begin
  196.             eval := ln((1+t1)/(1-t1))/2;
  197.           End;
  198.  
  199.           19 : Begin
  200.             eval := arctan(t1)+pi/2;
  201.           End;
  202.  
  203.           20 : Begin
  204.             eval := ln((t1+1)/(t1-1))/2;
  205.           End;
  206.  
  207.           21 : Begin
  208.             eval := -t1;
  209.           End;
  210.  
  211.           Else
  212.             If copy(f, l, r-l+1) = 'PI' Then
  213.               eval := Pi
  214.             Else If copy(f, l, r-l+1) = 'E' Then
  215.               eval := 2.718281828
  216.             Else Begin
  217.               Val(copy(f, l, r-l+1), result, j);
  218.               If j = 0 Then Begin
  219.                 eval := result;
  220.               End Else Begin
  221.                 {here you can handle other variables}
  222.                 errnum := 5; eval := 0.0; Exit;
  223.               End;
  224.             End;
  225.  
  226.          End
  227.        End
  228.     End
  229.   End;
  230.  
  231. Begin
  232. {  errnum := 0;} eps := 1.0E-9;
  233.  
  234.   f := StripBlanks(UpStr(f));
  235.   Calculate := Eval(1, length(f));
  236. End;
  237.  
  238. Begin
  239. READLN(s);
  240. While length(s) > 0 do Begin
  241.   errnum := 0; x := calculate(s);
  242.   writeln('Ergebnis : ',x:14:6, ' Fehlercode : ', errnum);
  243.   readln(s);
  244. End;
  245. End.
  246.  
  247. {
  248. You have to write your own function STRIPBLANKS, which eliminates ALL
  249. blanks in a string. And the only variables supported are e and pi. But
  250. it is not difficult to handle other variables.
  251.  
  252. }